#include "FilePicker.h"
#include <QStandardPaths>
#include <QDebug>
#include <QFileInfo>
#include <QDir>
#include <QDateTime>
#include <QFile>
#include <QTextStream>
#include <QTextCodec>
#include <QRegExp>

FilePicker::FilePicker(QObject *parent)
    : QObject(parent)
    , m_settings(new QSettings("NutPi", "FilePicker", this))
{
    loadRecentFiles();
}

FilePicker::~FilePicker()
{
    saveRecentFiles();
}

void FilePicker::setSelectedFile(const QString &filePath)
{
    if (filePath.isEmpty()) {
        return;
    }
    
    // 验证文件是否存在
    QFileInfo fileInfo(filePath);
    if (!fileInfo.exists()) {
        emit errorOccurred(tr("文件不存在: %1").arg(filePath));
        return;
    }
    
    if (fileInfo.isDir()) {
        emit errorOccurred(tr("请选择文件，不是文件夹"));
        return;
    }
    
    // 更新文件信息
    updateFileInfo(filePath);
    addToRecentFiles(filePath);
    emit fileSelected(filePath);
    emit selectionChanged();
}

void FilePicker::setSelectedFiles(const QStringList &filePaths)
{
    QStringList validFiles;
    
    for (const QString &filePath : filePaths) {
        QFileInfo fileInfo(filePath);
        if (fileInfo.exists() && fileInfo.isFile()) {
            validFiles.append(filePath);
        }
    }
    
    if (validFiles.isEmpty()) {
        emit errorOccurred(tr("没有有效的文件"));
        return;
    }
    
    m_selectedFiles = validFiles;
    
    // 更新第一个文件的信息
    if (!validFiles.isEmpty()) {
        updateFileInfo(validFiles.first());
        addToRecentFiles(validFiles.first());
    }
    
    emit filesSelected(validFiles);
    emit selectionChanged();
}

void FilePicker::setSelectedDirectory(const QString &dirPath)
{
    if (dirPath.isEmpty()) {
        return;
    }
    
    QFileInfo dirInfo(dirPath);
    if (!dirInfo.exists()) {
        emit errorOccurred(tr("文件夹不存在: %1").arg(dirPath));
        return;
    }
    
    if (!dirInfo.isDir()) {
        emit errorOccurred(tr("路径不是文件夹: %1").arg(dirPath));
        return;
    }
    
    m_selectedDirectory = dirInfo.absoluteFilePath();
    emit directorySelected(m_selectedDirectory);
}

void FilePicker::clearSelection()
{
    if (!m_filePath.isEmpty()) {
        m_filePath.clear();
        m_fileName.clear();
        m_fileSize.clear();
        m_fileExtension.clear();
        m_fileType.clear();
        m_fileModifiedTime.clear();
        m_selectedFiles.clear();
        m_selectedDirectory.clear();
        emit selectionChanged();
    }
}

QString FilePicker::getFileInfo(const QString &filePath)
{
    if (filePath.isEmpty()) {
        return QString();
    }
    
    QFileInfo fileInfo(filePath);
    if (!fileInfo.exists()) {
        emit errorOccurred(tr("文件不存在: %1").arg(filePath));
        return QString();
    }
    
    QString info;
    info += tr("文件名: %1\n").arg(fileInfo.fileName());
    info += tr("路径: %1\n").arg(fileInfo.absolutePath());
    info += tr("大小: %1\n").arg(formatFileSize(fileInfo.size()));
    info += tr("扩展名: %1\n").arg(fileInfo.suffix());
    info += tr("类型: %1\n").arg(detectFileType(fileInfo));
    info += tr("修改时间: %1").arg(fileInfo.lastModified().toString("yyyy-MM-dd HH:mm:ss"));
    
    return info;
}

bool FilePicker::fileExists(const QString &filePath)
{
    return QFileInfo::exists(filePath);
}

QString FilePicker::getDirectory(const QString &filePath)
{
    QFileInfo fileInfo(filePath);
    return fileInfo.absolutePath();
}

bool FilePicker::copyFile(const QString &sourcePath, const QString &destPath)
{
    if (!QFile::exists(sourcePath)) {
        emit errorOccurred(tr("源文件不存在: %1").arg(sourcePath));
        emit fileOperationCompleted("copy", false);
        return false;
    }
    
    // 如果目标文件已存在，先删除
    if (QFile::exists(destPath)) {
        if (!QFile::remove(destPath)) {
            emit errorOccurred(tr("无法删除目标文件: %1").arg(destPath));
            emit fileOperationCompleted("copy", false);
            return false;
        }
    }
    
    bool success = QFile::copy(sourcePath, destPath);
    emit fileOperationCompleted("copy", success);
    
    if (!success) {
        emit errorOccurred(tr("复制文件失败: %1 -> %2").arg(sourcePath, destPath));
    }
    
    return success;
}

bool FilePicker::moveFile(const QString &sourcePath, const QString &destPath)
{
    if (!QFile::exists(sourcePath)) {
        emit errorOccurred(tr("源文件不存在: %1").arg(sourcePath));
        emit fileOperationCompleted("move", false);
        return false;
    }
    
    // 如果目标文件已存在，先删除
    if (QFile::exists(destPath)) {
        if (!QFile::remove(destPath)) {
            emit errorOccurred(tr("无法删除目标文件: %1").arg(destPath));
            emit fileOperationCompleted("move", false);
            return false;
        }
    }
    
    bool success = QFile::rename(sourcePath, destPath);
    emit fileOperationCompleted("move", success);
    
    if (!success) {
        emit errorOccurred(tr("移动文件失败: %1 -> %2").arg(sourcePath, destPath));
    }
    
    return success;
}

bool FilePicker::deleteFile(const QString &filePath)
{
    if (!QFile::exists(filePath)) {
        emit errorOccurred(tr("文件不存在: %1").arg(filePath));
        emit fileOperationCompleted("delete", false);
        return false;
    }
    
    bool success = QFile::remove(filePath);
    emit fileOperationCompleted("delete", success);
    
    if (!success) {
        emit errorOccurred(tr("删除文件失败: %1").arg(filePath));
    }
    
    return success;
}

bool FilePicker::createDirectory(const QString &dirPath)
{
    QDir dir;
    bool success = dir.mkpath(dirPath);
    emit fileOperationCompleted("createDirectory", success);
    
    if (!success) {
        emit errorOccurred(tr("创建文件夹失败: %1").arg(dirPath));
    }
    
    return success;
}

QString FilePicker::readTextFile(const QString &filePath, int maxSize)
{
    if (!QFile::exists(filePath)) {
        emit errorOccurred(tr("文件不存在: %1").arg(filePath));
        return QString();
    }
    
    QFileInfo fileInfo(filePath);
    if (fileInfo.size() > maxSize) {
        emit errorOccurred(tr("文件太大，超过限制: %1 MB").arg(maxSize / (1024 * 1024)));
        return QString();
    }
    
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        emit errorOccurred(tr("无法打开文件: %1").arg(filePath));
        return QString();
    }
    
    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString content = in.readAll();
    file.close();
    
    return content;
}

bool FilePicker::writeTextFile(const QString &filePath, const QString &content)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        emit errorOccurred(tr("无法写入文件: %1").arg(filePath));
        return false;
    }
    
    QTextStream out(&file);
    out.setCodec("UTF-8");
    out << content;
    file.close();
    
    return true;
}

void FilePicker::addToRecentFiles(const QString &filePath)
{
    if (filePath.isEmpty() || !QFile::exists(filePath)) {
        return;
    }
    
    // 移除已存在的相同路径
    m_recentFiles.removeAll(filePath);
    
    // 添加到开头
    m_recentFiles.prepend(filePath);
    
    // 限制数量
    while (m_recentFiles.size() > MAX_RECENT_FILES) {
        m_recentFiles.removeLast();
    }
    
    saveRecentFiles();
    emit recentFilesChanged();
}

void FilePicker::clearRecentFiles()
{
    m_recentFiles.clear();
    saveRecentFiles();
    emit recentFilesChanged();
}

void FilePicker::removeRecentFile(const QString &filePath)
{
    m_recentFiles.removeAll(filePath);
    saveRecentFiles();
    emit recentFilesChanged();
}

QString FilePicker::getFileType(const QString &filePath)
{
    QFileInfo fileInfo(filePath);
    return detectFileType(fileInfo);
}

QString FilePicker::getFileIcon(const QString &filePath)
{
    QFileInfo fileInfo(filePath);
    QString extension = fileInfo.suffix().toLower();
    
    // 根据扩展名返回图标emoji
    if (extension == "png" || extension == "jpg" || extension == "jpeg" || 
        extension == "gif" || extension == "bmp" || extension == "svg") {
        return "🖼️";
    } else if (extension == "txt" || extension == "md" || extension == "log") {
        return "📄";
    } else if (extension == "pdf") {
        return "📕";
    } else if (extension == "doc" || extension == "docx") {
        return "📘";
    } else if (extension == "xls" || extension == "xlsx") {
        return "📊";
    } else if (extension == "mp3" || extension == "wav" || extension == "flac") {
        return "🎵";
    } else if (extension == "mp4" || extension == "avi" || extension == "mkv") {
        return "🎬";
    } else if (extension == "zip" || extension == "rar" || extension == "7z") {
        return "📦";
    } else if (extension == "exe" || extension == "app") {
        return "⚙️";
    } else {
        return "📎";
    }
}

QStringList FilePicker::searchFiles(const QString &directory, const QString &pattern)
{
    QStringList results;
    QDir dir(directory);
    
    if (!dir.exists()) {
        emit errorOccurred(tr("目录不存在: %1").arg(directory));
        return results;
    }
    
    // 使用通配符搜索
    dir.setNameFilters(QStringList() << pattern);
    dir.setFilter(QDir::Files | QDir::NoSymLinks);
    
    QFileInfoList fileList = dir.entryInfoList();
    for (const QFileInfo &fileInfo : fileList) {
        results.append(fileInfo.absoluteFilePath());
    }
    
    return results;
}

void FilePicker::updateFileInfo(const QString &filePath)
{
    QFileInfo fileInfo(filePath);
    
    m_filePath = fileInfo.absoluteFilePath();
    m_fileName = fileInfo.fileName();
    m_fileSize = formatFileSize(fileInfo.size());
    m_fileExtension = fileInfo.suffix();
    m_fileType = detectFileType(fileInfo);
    m_fileModifiedTime = fileInfo.lastModified().toString("yyyy-MM-dd HH:mm:ss");
}

QString FilePicker::formatFileSize(qint64 bytes) const
{
    const qint64 KB = 1024;
    const qint64 MB = KB * 1024;
    const qint64 GB = MB * 1024;
    
    if (bytes >= GB) {
        return QString("%1 GB").arg(QString::number(bytes / (double)GB, 'f', 2));
    } else if (bytes >= MB) {
        return QString("%1 MB").arg(QString::number(bytes / (double)MB, 'f', 2));
    } else if (bytes >= KB) {
        return QString("%1 KB").arg(QString::number(bytes / (double)KB, 'f', 2));
    } else {
        return QString("%1 字节").arg(bytes);
    }
}

QString FilePicker::detectFileType(const QFileInfo &fileInfo) const
{
    if (fileInfo.isDir()) {
        return tr("文件夹");
    }
    
    QString extension = fileInfo.suffix().toLower();
    
    if (extension == "png" || extension == "jpg" || extension == "jpeg" || 
        extension == "gif" || extension == "bmp" || extension == "svg" || 
        extension == "webp") {
        return tr("图片");
    } else if (extension == "txt" || extension == "md" || extension == "log" || 
               extension == "json" || extension == "xml" || extension == "html") {
        return tr("文本");
    } else if (extension == "pdf") {
        return tr("PDF文档");
    } else if (extension == "doc" || extension == "docx") {
        return tr("Word文档");
    } else if (extension == "xls" || extension == "xlsx") {
        return tr("Excel表格");
    } else if (extension == "mp3" || extension == "wav" || extension == "flac" || 
               extension == "aac" || extension == "ogg") {
        return tr("音频");
    } else if (extension == "mp4" || extension == "avi" || extension == "mkv" || 
               extension == "mov" || extension == "wmv" || extension == "flv") {
        return tr("视频");
    } else if (extension == "zip" || extension == "rar" || extension == "7z" || 
               extension == "tar" || extension == "gz") {
        return tr("压缩包");
    } else if (extension == "exe" || extension == "app" || extension == "dmg") {
        return tr("应用程序");
    } else if (extension.isEmpty()) {
        return tr("未知类型");
    } else {
        return tr("%1文件").arg(extension.toUpper());
    }
}

void FilePicker::loadRecentFiles()
{
    m_recentFiles.clear();
    int size = m_settings->beginReadArray("recentFiles");
    for (int i = 0; i < size; ++i) {
        m_settings->setArrayIndex(i);
        QString filePath = m_settings->value("path").toString();
        if (QFile::exists(filePath)) {
            m_recentFiles.append(filePath);
        }
    }
    m_settings->endArray();
}

void FilePicker::saveRecentFiles()
{
    m_settings->beginWriteArray("recentFiles");
    for (int i = 0; i < m_recentFiles.size(); ++i) {
        m_settings->setArrayIndex(i);
        m_settings->setValue("path", m_recentFiles.at(i));
    }
    m_settings->endArray();
    m_settings->sync();
}
